package com.harry.basis;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import lombok.Getter;

/**
 * 子类可动态获取真实泛型的抽象类
 */
public abstract class PureGeneric<T> {

	public PureGeneric() {
		loadEntityClass();
	}

	@Getter
	private Class<T> entityClass;

	/**
	 * 在子类动态获取泛型的真实类型
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	private void loadEntityClass() {
		Type genType = getClass();
		while (Class.class.isInstance(genType) && null != (genType = ((Class<?>) genType).getGenericSuperclass())) {
			if (ParameterizedType.class.isInstance(genType)) {
				Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
				if (params.length > 0) {
					if (Class.class.isInstance(params[0])) {
						entityClass = (Class) params[0];
					}
				}
				break;
			}
		}
	}

	/**
	 * 使用 CGLib 动态代理创建新类时，无法获取到泛型的真实类型，故增加一个手动绑定泛型类型的函数
	 * 
	 * @param entityClass
	 * @throws Exception
	 */
	public void bindEntityClass(Class<T> entityClass) throws Exception {
		if (this.entityClass == null) {
			this.entityClass = entityClass;
		} else {
			throw new Exception("Entity class had already been bound.");
		}
	}
}
